﻿using Windows.Storage;
using Windows.System;
using Microsoft.Windows.AppNotifications;

namespace DimensionsHelper.Client.WinUi.Services;

public class AppNotificationService(INavigationService navigationService) : IAppNotificationService
{
    public void Initialize()
    {
        AppNotificationManager.Default.NotificationInvoked += OnNotificationInvoked;

        AppNotificationManager.Default.Register();
    }

    public bool Show(string payload)
    {
        AppNotification? appNotification = new(payload);

        AppNotificationManager.Default.Show(appNotification);

        return appNotification.Id != 0;
    }

    public NameValueCollection ParseArguments(string arguments)
    {
        NameValueCollection args = [];

        int pos = 0;
        bool meetEqual = false;
        StringBuilder key = new();
        StringBuilder value = new();

        while (pos < arguments.Length)
        {
            char ch = arguments[pos];

            if (ch == ';' || pos == arguments.Length - 1)
            {
                if (ch != ';' && meetEqual)
                {
                    value.Append(ch);
                }

                if (key.Length > 0)
                {
                    args[key.ToString()] = value.ToString();
                }

                key.Clear();
                value.Clear();
                meetEqual = false;
            }
            else if (meetEqual)
            {
                value.Append(ch);
            }
            else if (ch == '=')
            {
                meetEqual = true;
            }
            else
            {
                key.Append(ch);
            }

            pos++;
        }

        return args;
    }

    public void Unregister() => AppNotificationManager.Default.Unregister();

    ~AppNotificationService()
    {
        Unregister();
    }

    public void OnNotificationInvoked(AppNotificationManager sender, AppNotificationActivatedEventArgs args)
    {
        App.DispatcherQueue.TryEnqueue(async void () =>
        {
            try
            {
                NameValueCollection arguments = ParseArguments(args.Argument);

                // dir
                string? dir = arguments["dir"];

                if (!string.IsNullOrEmpty(dir))
                {
                    await Launcher.LaunchFolderAsync(await StorageFolder.GetFolderFromPathAsync(dir));
                    return;
                }

                string? target = arguments["target"];
                string? detail = arguments["detail"];

                if (string.IsNullOrEmpty(target))
                {
                    return;
                }

                navigationService.NavigateTo(target, detail);
            }
            catch (Exception)
            {
                // ignored
            }
        });
    }
}